package com.huashi.dealer;

import com.baomidou.mybatisplus.generator.FastAutoGenerator;
import com.baomidou.mybatisplus.generator.config.OutputFile;
import com.huashi.dealer.core.template.BtlTemplateEngine;

import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;

/**
 * 自定义模板引擎，支持模块名变量
 */
// 删除CustomBtlTemplateEngine类（如果有）

public class CodeGenerator {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);

        // 1. 交互输入模块名
        System.out.print("请输入业务模块名（如 user、order）：");
        String module = scanner.nextLine().trim();

        // 2. 交互输入表名
        System.out.print("请输入要生成的表名（多个用逗号分隔）：");
        String tables = scanner.nextLine().trim();

        // 3. 自动生成实体类名（取第一个表名）
        String firstTable = tables.split(",")[0].trim();
        String entityName = convertTableNameToEntityName(firstTable);
        System.out.println("自动生成的实体类名: " + entityName);

        // 4. 自动获取表注释（这里暂时使用表名作为注释，实际项目中可以从数据库获取）
        String tableComment = firstTable;
        System.out.println("使用表名作为注释: " + tableComment);

        // 5. 获取当前日期
        String currentDate = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));

        // 6. 配置输出路径
        Map<OutputFile, String> pathInfo = new HashMap<>();
        String basePath = System.getProperty("user.dir") + "/src/main/java/com/huashi/dealer/modular/" + module;
        pathInfo.put(OutputFile.xml, basePath + "/mapper/mapping");
        pathInfo.put(OutputFile.entity, basePath + "/entity");
        pathInfo.put(OutputFile.controller, basePath + "/controller");
        pathInfo.put(OutputFile.service, basePath + "/service");
        pathInfo.put(OutputFile.serviceImpl, basePath + "/service/impl");
        pathInfo.put(OutputFile.mapper, basePath + "/mapper");


        // 7. 生成基础代码
        FastAutoGenerator.create(
                        "jdbc:mysql://localhost:3306/snowy?useSSL=false&serverTimezone=Asia/Shanghai",
                        "root",
                        "as782310197")
                .globalConfig(builder -> {
                    builder.author("谭陈强")
                            .outputDir(System.getProperty("user.dir") + "/src/main/java");
                })
                .packageConfig(builder -> {
                    builder.parent("com.huashi.dealer.modular." + module)
                            .service("service")
                            .serviceImpl("service.impl")
                            .pathInfo(pathInfo);
                })
                .strategyConfig(builder -> {
                    builder.addInclude(tables.split(","));

                    // Controller 配置
                    builder.controllerBuilder()
                            .enableRestStyle()
                            .enableHyphenStyle()
                            .build();

                    // Entity 配置
                    builder.entityBuilder()
                            .enableLombok()
                            .enableTableFieldAnnotation()
                            .build();

                    // Service 配置
                    builder.serviceBuilder()
                            .formatServiceFileName("%sService")
                            .formatServiceImplFileName("%sServiceImpl")
                            .build();

                    // Mapper 配置
                    builder.mapperBuilder()
                            .enableMapperAnnotation()
                            .build();
                })
                .injectionConfig(builder -> {
                    Map<String, Object> customMap = new HashMap<>();
                    customMap.put("moduleName", module);
                    builder.customMap(customMap);
                })
                .templateConfig(builder -> {
                    // 使用自定义模板（templates目录下的vm文件）
                    String templatePath = "/templates/";
                    System.out.println("使用模板路径: " + templatePath);

                    builder.entity(templatePath + "Entity.java.vm");
                    builder.controller(templatePath + "Controller.java.vm");
                    builder.service(templatePath + "Service.java.vm");
                    builder.serviceImpl(templatePath + "ServiceImpl.java.vm");
                    builder.mapper(templatePath + "Mapper.java.vm");
                    builder.xml(templatePath + "Mapper.xml.vm");
                })
                .templateEngine(new BtlTemplateEngine())
                .execute();

        // 手动生成Param文件（使用现有模板）
        generateParamFiles(module, tables.split(","), entityName, tableComment, currentDate);
        System.out.println("输出的entityName为：" + entityName);
        System.out.println("代码生成完成！");
        System.out.println("生成的文件结构：");
        System.out.println("├── entity/          # 实体类");
        System.out.println("├── controller/      # 控制器");
        System.out.println("├── service/         # 服务接口");
        System.out.println("│   └── impl/       # 服务实现");
        System.out.println("├── mapper/          # 数据访问层");
        System.out.println("│   └── mapping/    # XML映射文件");
        System.out.println("└── param/           # 参数类（使用现有模板引擎）");
    }

    /**
     * 将表名转换为驼峰命名的实体类名
     * 例如：biz_company -> BizCompany
     */
    private static String convertTableNameToEntityName(String tableName) {
        if (tableName == null || tableName.trim().isEmpty()) {
            return "Entity";
        }

        // 移除表名前缀（如果有的话）
        String name = tableName.toLowerCase();

        // 常见的表名前缀
//        String[] prefixes = {"t_", "tb_", "table_", "sys_", "biz_", "app_", "user_", "order_", "product_"};
//        for (String prefix : prefixes) {
//            if (name.startsWith(prefix)) {
//                name = name.substring(prefix.length());
//                break;
//            }
//        }

        // 转换为驼峰命名
        StringBuilder result = new StringBuilder();
        boolean nextUpper = true;

        for (char c : name.toCharArray()) {
            if (c == '_') {
                nextUpper = true;
            } else {
                if (nextUpper) {
                    result.append(Character.toUpperCase(c));
                    nextUpper = false;
                } else {
                    result.append(c);
                }
            }
        }

        return result.toString();
    }

    /**
     * 手动生成Param文件（使用现有模板）
     */
    private static void generateParamFiles(String module, String[] tableNames, String entityName, String tableComment, String currentDate) {
        String basePath = System.getProperty("user.dir") + "/src/main/java/com/huashi/dealer/modular/" + module;
        String paramPath = basePath + "/param";

        // 确保param目录存在
        new java.io.File(paramPath).mkdirs();

        // 生成AddParam.java
        generateAddParam(paramPath, entityName, tableComment, currentDate, module);

        // 生成EditParam.java
        generateEditParam(paramPath, entityName, tableComment, currentDate, module);

        // 生成IdParam.java
        generateIdParam(paramPath, entityName, tableComment, currentDate, module);

        // 生成PageParam.java
        generatePageParam(paramPath, entityName, tableComment, currentDate, module);
    }

    private static void generateAddParam(String paramPath, String entityName, String tableComment, String currentDate, String module) {
        String content = "package com.huashi.dealer.modular." + module + ".param;\n\n" +
                "import io.swagger.v3.oas.annotations.media.Schema;\n" +
                "import lombok.Getter;\n" +
                "import lombok.Setter;\n\n" +
                "import jakarta.validation.constraints.NotBlank;\n" +
                "import jakarta.validation.constraints.NotNull;\n" +
                "import java.math.BigDecimal;\n" +
                "import java.util.Date;\n\n" +
                "/**\n" +
                " * " + tableComment + "添加参数\n" +
                " *\n" +
                " * @author 谭陈强\n" +
                " * @since " + currentDate + "\n" +
                " */\n" +
                "@Getter\n" +
                "@Setter\n" +
                "public class " + entityName + "AddParam {\n\n" +
                "    // TODO: 根据实际字段添加参数\n" +
                "}";

        writeFile(paramPath + "/" + entityName + "AddParam.java", content);
    }

    private static void generateEditParam(String paramPath, String entityName, String tableComment, String currentDate, String module) {
        String content = "package com.huashi.dealer.modular." + module + ".param;\n\n" +
                "import io.swagger.v3.oas.annotations.media.Schema;\n" +
                "import lombok.Getter;\n" +
                "import lombok.Setter;\n\n" +
                "import jakarta.validation.constraints.NotBlank;\n" +
                "import jakarta.validation.constraints.NotNull;\n" +
                "import java.math.BigDecimal;\n" +
                "import java.util.Date;\n\n" +
                "/**\n" +
                " * " + tableComment + "编辑参数\n" +
                " *\n" +
                " * @author 谭陈强\n" +
                " * @since " + currentDate + "\n" +
                " */\n" +
                "@Getter\n" +
                "@Setter\n" +
                "public class " + entityName + "EditParam {\n\n" +
                "    /** ID */\n" +
                "    @Schema(description = \"ID\")\n" +
                "    @NotNull(message = \"ID不能为空\")\n" +
                "    private Long id;\n" +
                "}";

        writeFile(paramPath + "/" + entityName + "EditParam.java", content);
    }

    private static void generateIdParam(String paramPath, String entityName, String tableComment, String currentDate, String module) {
        String content = "package com.huashi.dealer.modular." + module + ".param;\n\n" +
                "import io.swagger.v3.oas.annotations.media.Schema;\n" +
                "import lombok.Getter;\n" +
                "import lombok.Setter;\n\n" +
                "import jakarta.validation.constraints.NotNull;\n\n" +
                "/**\n" +
                " * " + tableComment + "ID参数\n" +
                " *\n" +
                " * @author 谭陈强\n" +
                " * @since " + currentDate + "\n" +
                " */\n" +
                "@Getter\n" +
                "@Setter\n" +
                "public class " + entityName + "IdParam {\n\n" +
                "    /** ID */\n" +
                "    @Schema(description = \"ID\")\n" +
                "    @NotNull(message = \"ID不能为空\")\n" +
                "    private Long id;\n" +
                "}";

        writeFile(paramPath + "/" + entityName + "IdParam.java", content);
    }

    private static void generatePageParam(String paramPath, String entityName, String tableComment, String currentDate, String module) {
        String content = "package com.huashi.dealer.modular." + module + ".param;\n\n" +
                "import io.swagger.v3.oas.annotations.media.Schema;\n" +
                "import lombok.Getter;\n" +
                "import lombok.Setter;\n" +
                "import com.huashi.dealer.core.page.CommonPageRequest;\n\n" +
                "/**\n" +
                " * " + tableComment + "分页参数\n" +
                " *\n" +
                " * @author 谭陈强\n" +
                " * @since " + currentDate + "\n" +
                " */\n" +
                "@Getter\n" +
                "@Setter\n" +
                "public class " + entityName + "PageParam extends CommonPageRequest {\n\n" +
                "    /** 排序字段 */\n" +
                "    @Schema(description = \"排序字段\")\n" +
                "    private String sortField;\n\n" +
                "    /** 排序方式 */\n" +
                "    @Schema(description = \"排序方式\")\n" +
                "    private String sortOrder;\n" +
                "}";

        writeFile(paramPath + "/" + entityName + "PageParam.java", content);
    }

    private static void writeFile(String filePath, String content) {
        try (java.io.FileWriter writer = new java.io.FileWriter(filePath)) {
            writer.write(content);
            System.out.println("生成文件: " + filePath);
        } catch (java.io.IOException e) {
            System.err.println("生成文件失败: " + filePath);
            e.printStackTrace();
        }
    }
} 